/**
 * 
 */
package slhs.tempo.pivotTableUtilities;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JToggleButton;
import javax.swing.border.TitledBorder;
import javax.swing.table.TableModel;

import org.openswing.swing.client.ExportButton;
import org.openswing.swing.client.FilterButton;
import org.openswing.swing.client.ReloadButton;
import org.openswing.swing.message.receive.java.Response;
import org.openswing.swing.pivottable.client.DataFieldRenderer;
import org.openswing.swing.pivottable.client.PivotTable;
import org.openswing.swing.pivottable.client.PivotTableController;
import org.openswing.swing.pivottable.java.ColumnField;
import org.openswing.swing.pivottable.java.DataField;
import org.openswing.swing.pivottable.java.PivotTableParameters;
import org.openswing.swing.pivottable.java.RowField;
import org.openswing.swing.pivottable.server.PivotTableEngine;
import org.openswing.swing.pivottable.tablemodelreaders.server.TableModelReader;

import slhs.tempo.TableAnalyzer.SaveCurrentState;
import slhs.tempo.TableAnalyzer.TableModelDataConverter;
import slhs.tempo.TableAnalyzer.TablePanelHandler;
import slhs.tempo.scriptGenerator.TitledBorderFactory;
import slhs.tempo.scriptGenerator.UtilityConstants;

/**
 * PivotTablePanelHandler.java
 * 
 * @author Swapnil Devikar
 * 
 */
public class PivotTableFrameHandler extends JFrame {

    private final TablePanelHandler tablePanelHandlerObject;
    private ReloadButton reloadButton;
    private ExportButton exportButton;
    private FilterButton filterButton;
    private JToggleButton expRowButton;
    private JToggleButton expColumnButton;

    // here are declarations for the controls you created
    private JPanel pivotTableButtonsPanel;
    private PivotTable pivotTable;

    private TitledBorder pivotTableParametersConfigPanelBorder;
    private TitledBorder pivotTableButtonsPanelBorder;

    public PivotTableFrameHandler(TablePanelHandler tablePanelHandlerObject) {
	this.tablePanelHandlerObject = tablePanelHandlerObject;
	initComponents();
	addComponents();
	configurePivotTable();
	populatePivotTableConfigurationOptions();
	this.setVisible(true);
	this.setSize(800, 900);
    }

    /**
     * 
     */
    private void configurePivotTable() {
	JTable table = tablePanelHandlerObject.getTable();
	// prepare a data reader
	TableModelDataConverter dataConverter = new TableModelDataConverter(table.getModel());
	dataConverter.startConversion();
	TableModel formattedTableModel = dataConverter.getDataConvertedModel();
	TableModelReader reader = new TableModelReader(formattedTableModel);

	final PivotTableEngine engine = new PivotTableEngine(reader);

	pivotTable.setController(new PivotTableController() {

	    @Override
	    public Response getPivotTableModel(PivotTableParameters pars) {
		long t = System.currentTimeMillis();
		Response res = engine.getPivotTableModel(pars);
		return res;
	    }

	});

	String sampleRowCategory = (String) tablePanelHandlerObject.getColumnDataVector().elementAt(0); // subject name
	RowField rowFieldCategory = new RowField(sampleRowCategory, 100);
	// apply category to table
	pivotTable.getAllRowFields().add(rowFieldCategory);
	pivotTable.addRowField(rowFieldCategory);

	String sampleColumnCategoryProbe = (String) tablePanelHandlerObject.getColumnDataVector().elementAt(12); // Probe/ctl
	ColumnField columnFieldProbe = new ColumnField(sampleColumnCategoryProbe);
	// apply category to all column fields in table
	pivotTable.getAllColumnFields().add(columnFieldProbe);
	pivotTable.addColumnField(columnFieldProbe);

	String sampledataField = (String) tablePanelHandlerObject.getColumnDataVector().elementAt(5); // Reaction time
	DataField dataFieldResponseTime = new DataField(sampledataField, 100);
	pivotTable.getAllDataFields().add(dataFieldResponseTime);
	pivotTable.addDataField(dataFieldResponseTime);

	pivotTable.setDataFieldRenderer(new DataFieldRenderer());
    }

    /**
     * configure the pivot table
     */
    public  void configurePivotTable(JTable table, Object[] rowFieldCategories, Object[] columnFields,
	    Object[] dataFields) {

	for (Object columnField : columnFields) {
	    try {
		pivotTable.removeColumnField(new ColumnField(columnField.toString()));
	    } catch (Exception e) {
	    }

	}

	for (Object rowField : rowFieldCategories) {

	    try {
		pivotTable.removeRowField(new RowField(rowField.toString(), 100));
	    } catch (Exception e) {
	    }
	}
	// prepare a data reader
	TableModelDataConverter dataConverter = new TableModelDataConverter(table.getModel());
	dataConverter.startConversion();
	TableModel formattedTableModel = dataConverter.getDataConvertedModel();
	TableModelReader reader = new TableModelReader(formattedTableModel);

	final PivotTableEngine engine = new PivotTableEngine(reader);

	pivotTable.setController(new PivotTableController() {

	    @Override
	    public Response getPivotTableModel(PivotTableParameters pars) {
		System.out.println("Getting response");
		long t = System.currentTimeMillis();
		Response res = engine.getPivotTableModel(pars);
		System.out.println("error response from current pivot table engine? :\t" + res.getErrorMessage());
		System.out.println("Analysis time: " + (System.currentTimeMillis() - t) + "ms");
		return res;
	    }

	});

	// add row field categories
	for (Object rowCategory : rowFieldCategories) {
	    // String sampleRowCategory = (String) tablePanelHandlerObject.getColumnDataVector().elementAt(3);
	    RowField rowFieldCategory = new RowField(rowCategory.toString(), 100);
	    // apply category to table
	    ArrayList allRowFields = pivotTable.getAllRowFields();
	    allRowFields.add(rowFieldCategory);
	    pivotTable.addRowField(rowFieldCategory);
	    System.out.println("Adding row category:\t" + rowCategory.toString());

	}

	// add sample column fields in pivot table
	// will need a string aggregator for probes (for items analysis)
	for (Object columnField : columnFields) {
	    // String sampleColumnCategoryProbe = (String) tablePanelHandlerObject.getColumnDataVector().elementAt(0);
	    ColumnField columnFieldProbe = new ColumnField(columnField.toString());
	    // apply category to all column fields in table
	    ArrayList allColumnFields = pivotTable.getAllColumnFields();
	    System.out.println("Adding column field:\t" + columnField.toString());

	    allColumnFields.add(columnFieldProbe);
	    pivotTable.addColumnField(columnFieldProbe);

	}

	// add sample data field to pivot table
	for (Object dataField : dataFields) {
	    // String sampledataField = (String) tablePanelHandlerObject.getColumnDataVector().elementAt(5);
	    System.out.println("Adding data field:\t" + dataField.toString());
	    DataField dataFieldResponseTime = new DataField(dataField.toString(), 100);
	    pivotTable.getAllDataFields().add(dataFieldResponseTime);
	    pivotTable.addDataField(dataFieldResponseTime);

	}

	// add row, column and data fields in pivot table

	pivotTable.setDataFieldRenderer(new DataFieldRenderer());
	pivotTable.reload();

	// UI configuration
    }

    /**
     * Initialize the components on the screen
     */
    private void initComponents() {
	reloadButton = new ReloadButton();
	exportButton = new ExportButton();
	filterButton = new FilterButton();
	expRowButton = new JToggleButton("Expand/collapse row");
	expColumnButton = new JToggleButton("Expand/collapse column");
	pivotTable = new PivotTable();
	pivotTableButtonsPanel = new JPanel();

    }

    /**
     * Add components to their placeholders
     */
    private void addComponents() {

	TitledBorderFactory titledBorderFactory = new TitledBorderFactory(Color.GRAY, "sansserif", Font.BOLD
		+ Font.ITALIC, UtilityConstants.BORDER_FONT_SIZE);

	pivotTableButtonsPanelBorder = titledBorderFactory.getTitledBorder("Edit/Export Options");
	pivotTableButtonsPanel.setBorder(pivotTableButtonsPanelBorder);

	this.getContentPane().add(pivotTableButtonsPanel, BorderLayout.NORTH);
	this.getContentPane().add(pivotTable, BorderLayout.CENTER);

	JPanel pivotTableParametersConfigPanel = new PivotTableParametersConfigPanelHandler(tablePanelHandlerObject)
		.getPanel();

	pivotTableParametersConfigPanelBorder = titledBorderFactory.getTitledBorder("Pivot Table Configurations");
	pivotTableParametersConfigPanel.setBorder(pivotTableParametersConfigPanelBorder);

	this.getContentPane().add(pivotTableParametersConfigPanel, BorderLayout.WEST);
	pivotTableButtonsPanel.add(expColumnButton, "expColumnButton");
	pivotTableButtonsPanel.add(filterButton, "filterButton");
	pivotTableButtonsPanel.add(expRowButton, "expRowButton");
	pivotTableButtonsPanel.add(exportButton, "exportButton");
	pivotTableButtonsPanel.add(reloadButton, "reloadButton");

	pivotTable.setExportButton(exportButton);
	pivotTable.setFilterButton(filterButton);
	pivotTable.setReloadButton(reloadButton);
	pivotTable.setAutoCompile(true);
	pivotTable.setForeground(Color.WHITE);
	expRowButton.addActionListener(new GridFrame_expRowButton_actionAdapter(this));
	expColumnButton.addActionListener(new GridFrame_expColButton_actionAdapter(this));

    }

    /**
     * This is a helper method to populate fields on the pivot table configuration panel handler
     */
    private void populatePivotTableConfigurationOptions() {
	String tableNamesList[] = tablePanelHandlerObject.getTabsList();
	PivotTableParametersConfigPanelHandler.updateTableList(tableNamesList);

	int selectedTabIndex = tablePanelHandlerObject.getSelectedTabIndex();
	JTable tableOnSelectedTab = SaveCurrentState.tableNameObjectHashmap.get(new Integer(selectedTabIndex));
	int numberOfColumns = tableOnSelectedTab.getColumnCount();
	String[] columnNamesList = new String[numberOfColumns];
	for (int columnIndex = 0; columnIndex < numberOfColumns; columnIndex++) {
	    columnNamesList[columnIndex] = tableOnSelectedTab.getColumnName(columnIndex);
	    System.out.println(columnNamesList[columnIndex]);
	}
	PivotTableParametersConfigPanelHandler.updateAvailableRowList(columnNamesList);
	PivotTableParametersConfigPanelHandler.updateAvailableColumnsList(columnNamesList);

    }

    class GridFrame_expRowButton_actionAdapter implements java.awt.event.ActionListener {
	PivotTableFrameHandler adaptee;

	GridFrame_expRowButton_actionAdapter(PivotTableFrameHandler adaptee) {
	    this.adaptee = adaptee;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
	    adaptee.expRowButton_actionPerformed(e);
	}
    }

    class GridFrame_expColButton_actionAdapter implements java.awt.event.ActionListener {
	PivotTableFrameHandler adaptee;

	GridFrame_expColButton_actionAdapter(PivotTableFrameHandler adaptee) {
	    this.adaptee = adaptee;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
	    adaptee.expColButton_actionPerformed(e);
	}
    }

    void expRowButton_actionPerformed(ActionEvent e) {
	if (pivotTable.getSelectedRow() == -1)
	    return;
	if (expRowButton.isSelected())
	    pivotTable.expandRow(pivotTable.getSelectedRow());
	else
	    pivotTable.collapseRow(pivotTable.getSelectedRow());
    }

    void expColButton_actionPerformed(ActionEvent e) {
	if (pivotTable.getSelectedColumn() == -1)
	    return;
	if (expColumnButton.isSelected())
	    pivotTable.expandColumn(pivotTable.getSelectedColumn());
	else
	    pivotTable.collapseColumn(pivotTable.getSelectedColumn());

    }

}
